/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.rainbow.xml;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.rainbow.annotation.AnnotationUtils;
import org.rainbow.annotation.xml.NodeAttr;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author hironaga
 */
class NodeAttrHandler extends XmlHandleComponent{

    private XmlCommonHandler commonHandler = XmlCommonHandler.getInstance();

    NodeAttrHandler() {}

    void writeElement(Annotation annotation, Method getter, Field field, Object obj,
            Document doc, String xpath, int index, Node parentElement, XmlHandleHelper helper)
                                                            throws IOException {

        //TODO 書込未対応
        //Annotation Content
        NodeAttr nodeAttrAnnt = (NodeAttr)annotation;
        String elementName = nodeAttrAnnt.elementName();

        //String textValuze;
        Object attrValue;

        try{
            //Method:"getter" invoke: get-property
            attrValue = getter.invoke(obj, new Object[0]);
        } catch (InvocationTargetException ex) {
            return;
        } catch (IllegalAccessException ex) {
            return;
        } catch (IllegalArgumentException ex) {
            return;
        } //try-catch

        //Add Node Attribute
//                        String elementName = getLastElementNameFromXpath(xpath);
//                        Node newElement = getLastElement(doc, xpath, elementName, index);
//                        if(newElement == null){
//                            newElement = appendElement(doc, parentNode, elementName);
    }

    void readElement(Annotation annotation, Method setter,
                          Field field, Object obj, Document doc, String xpath,
                                    Node parentElement, XmlHandleHelper helper)
             throws IOException, InstantiationException, IllegalAccessException{

        //Annotation Content
        NodeAttr nodeAttrAnnt = (NodeAttr)annotation;
        String elementName = nodeAttrAnnt.elementName();
        String attrName = nodeAttrAnnt.attrName();

        Node firstChild = parentElement.getFirstChild();

        Class<?> filedType = field.getType();
        Class<?> fieldContentsType = null;
        List list = null;
        if(AnnotationUtils.isCollection(filedType)){
            fieldContentsType = (Class)AnnotationUtils.getCollectionContentType(field);
            String childXpath = xpath + "/" +elementName;
            NodeList nodeList = commonHandler.getNodeList(doc, childXpath);
            if(nodeList == null || nodeList.getLength() == 0){
                return;
            }
            //TODO
            list = new ArrayList();
            int nodeLength = nodeList.getLength();
            loop0: //loop:Node-List
            for(int idx0=0; idx0<nodeLength; idx0++){
                String attrNodeValue = commonHandler.getNodeAttrValue(
                        commonHandler.getElementNode(nodeList.item(idx0)), attrName);
                list.add(commonHandler.getPropertyValue(attrNodeValue, fieldContentsType));
            }//loop0

            try{
                //Method:"setter" invoke: set-property
                setter.invoke(obj, new Object[]{ list } );
            } catch (IllegalArgumentException ex) {
            } catch (InvocationTargetException ex) {
            } finally{
                return;
            }//try-catch
        }


        loop3:
        while(firstChild != null){

            Node elementNode = commonHandler.getElementNode(firstChild);
            if(elementNode == null){
                break loop3;
            }
            else{
                String firstChildNodeName = elementNode.getNodeName();

                //compare "Node-ElementName" "elementName@annotation"
                if( (firstChildNodeName != null) &&
                        (firstChildNodeName.equals(elementName)) ){

                    String attrNodeValue = commonHandler.getNodeAttrValue(elementNode, attrName);

                    try{
                    //Method:"setter" invoke: set-property
                    setter.invoke(obj, new Object[]{
                        commonHandler.getPropertyValue(attrNodeValue, field.getType()) } );
                    } catch (IllegalArgumentException ex) {
                    } catch (InvocationTargetException ex) {
                    } finally{
                        return;
                    }//try-catch
                }//if
            }//if
            //Next Node
            firstChild = firstChild.getNextSibling();
        }//loop3

    }

    void overwriteElement(Annotation annotation, Method getter,
            Field field, Object obj, Document doc, String xpath, int index,
            Node parentElement, XmlHandleHelper helper) throws IOException {

        //TODO 更新未対応
        //Annotation Content
        NodeAttr nodeAttrAnnt = (NodeAttr)annotation;
        String elementName = nodeAttrAnnt.elementName();

        //String textValuze;
        Object attrValue;

        try{
            //Method:"getter" invoke: get-property
            attrValue = getter.invoke(obj, new Object[0]);
        } catch (InvocationTargetException ex) {
            return;
        } catch (IllegalAccessException ex) {
            return;
        } catch (IllegalArgumentException ex) {
            return;
        } //try-catch

        //Add Node Attribute
//                        String elementName = getLastElementNameFromXpath(xpath);
//                        Node newElement = getLastElement(doc, xpath, elementName, index);
//                        if(newElement == null){
//                            newElement = appendElement(doc, parentNode, elementName);
    }





}
